package com.reder.practice.resolver;

import com.reder.practice.common.annotation.FromSession;
import com.reder.practice.bean.Manager;
import com.reder.practice.bean.User;
import com.reder.practice.common.util.SessionUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.SessionAttributeMethodArgumentResolver;

import javax.servlet.http.HttpServletRequest;


/**
 * 会话中的用户信息自动注入视图解析器
 *
 * @author Fish
 * ------> 1149062639@qq.com
 * created by 2019/03/08 11:05:17
 */
@Slf4j
public class SessionUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    // 带有 FromSession 注解的数据将返回 true
    private boolean hasAnnotation(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(FromSession.class);
    }

    // 数据类型是 User 或 Manager 才会返回 true
    private boolean isUserOrManager(MethodParameter methodParameter) {
        return isUser(methodParameter) || isManager(methodParameter);
    }

    // 数据类型是 User 才会返回 true
    private boolean isUser(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(User.class);
    }

    // 数据类型是 Manager 才会返回 true
    private boolean isManager(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(Manager.class);
    }

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        // 只有标有注解和类型信息的才会进行注入
        return hasAnnotation(methodParameter) && isUserOrManager(methodParameter);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {

        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        if (request != null) {
            // 获取用户对象并返回
            return SessionUtil.userOf(request);
        }

        // 这种情况几乎不会发生
        return null;
    }
}
